package com.central.apps.service.impl;

import com.central.app.common.util.DateUtils;
import com.central.app.service.HandlerService;
import com.central.apps.common.constant.ProjectPlanConstant;
import com.central.apps.entity.MpxjBean;
import com.central.apps.entity.MpxjTaskBean;
import com.central.apps.service.TaskChangeService;
import com.central.apps.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 任务变更接口实现类
 *
 * @author 李大超
 * @date 2023/4/19
 */
@Slf4j
@Service
public class TaskChangeServiceImpl implements TaskChangeService {
    @Autowired
    private HandlerService handlerService;
    @Autowired
    private TaskService taskService;

    @Override
    public void updateRecordId(Integer proId, Integer tcId) throws Exception {
        taskService.updateRecordId("gq_taskchgdtl", " proid = " + proId + " and tcid = " + tcId);
    }

    @Override
    public Map<String, Object> viewTask(Integer proId, Integer tcId, Integer taskId) throws Exception {
        List<Map<String, Object>> list = handlerService.findBySql("select t.* from gq_taskchgdtl t where t.proid = " + proId + " and tcid = " + tcId + " and t.id =" + taskId);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public void updParentId(Integer proId, Integer tcId) throws Exception {
        taskService.updParentId("gq_taskchgdtl", " proid = " + proId + " and tcid = " + tcId, "taskchglevel");
    }

    @Override
    public void updPredecessors(Integer proId, Integer tcId) throws Exception {
        taskService.updPredecessors("gq_taskchgdtl", " proid = " + proId + " and tcid = " + tcId);
    }

    @Override
    public MpxjBean viewPlan(Integer proId, Integer tcId) throws Exception {
        // 查询年度计划信息
        List<Map<String, Object>> taskList = handlerService.findBySql("select * from gq_taskchgdtl where proid = " + proId + " and tcid = " + tcId + " order by recordId");

        // 组织WBS计划信息
        if (CollectionUtils.isNotEmpty(taskList)) {
            return combinePlanBean(taskList);
        }

        return null;
    }

    @Override
    public MpxjBean modifyPlan(MpxjBean mpxjBean, Integer proId, Integer tcId) throws Exception {
        Integer[] delTaskIds = mpxjBean.getDeletedTaskIds();
        if (delTaskIds != null && delTaskIds.length > 0) {
            StringBuilder sb = new StringBuilder();
            for (int delTaskId : delTaskIds) {
                sb.append(delTaskId).append(",");
            }
            sb.deleteCharAt(sb.length()-1);

            handlerService.updateBySql("delete from gq_taskchgdtl where id in ("+ sb.toString() + ")");
        }

        List<MpxjTaskBean> mpxjTaskBeanList = mpxjBean.getTasks();
        if (CollectionUtils.isNotEmpty(mpxjTaskBeanList)) {
            this.dealTask(mpxjTaskBeanList, proId, tcId);
        }

        // 查询最新的年度计划信息
        return this.viewPlan(proId, tcId);
    }

    /**
     * 组织年度计划WBS实体信息
     *
     * @param taskList
     * @return MpxjBean
     */
    private MpxjBean combinePlanBean(List<Map<String, Object>> taskList) throws Exception {
        if (CollectionUtils.isNotEmpty(taskList)) {
            // 组织项目文件主信息
            MpxjBean mpxjBean = new MpxjBean();
            mpxjBean.setSelectedRow(1);
            mpxjBean.setCanAdd(ProjectPlanConstant.CAN_ADD);
            mpxjBean.setCanWrite(ProjectPlanConstant.CAN_WRITE);
            mpxjBean.setCanWriteOnParent(ProjectPlanConstant.CAN_WRITE_ON_PARENT);
            mpxjBean.setZoom(ProjectPlanConstant.ZOOM);

            List<MpxjTaskBean> mpxjTaskBeanList = new LinkedList<>();
            for (Map<String, Object> taskMap : taskList) {
                // 组织项目任务信息
                MpxjTaskBean mpxjTaskBean = new MpxjTaskBean();
                mpxjTaskBean.setId(MapUtils.getString(taskMap, "id"));
                mpxjTaskBean.setName(MapUtils.getString(taskMap, "name"));
                mpxjTaskBean.setLevel(MapUtils.getInteger(taskMap, "taskchglevel"));
                mpxjTaskBean.setDescription(MapUtils.getString(taskMap, "description"));
                mpxjTaskBean.setProgress(MapUtils.getInteger(taskMap, "progress"));
                mpxjTaskBean.setProgressByWorklog(ProjectPlanConstant.PROGRESS_BY_WORKLOG);

                mpxjTaskBean.setTypeId(MapUtils.getString(taskMap, "typeId"));
                mpxjTaskBean.setType(MapUtils.getString(taskMap, "type"));
                mpxjTaskBean.setManager(MapUtils.getInteger(taskMap, "manager"));
                mpxjTaskBean.setManagerName(MapUtils.getString(taskMap, "managername"));
                mpxjTaskBean.setStatus(MapUtils.getString(taskMap, "status"));
                mpxjTaskBean.setTaskLevel(MapUtils.getString(taskMap, "tasklevel"));
                mpxjTaskBean.setDepends(MapUtils.getString(taskMap, "depends"));
                mpxjTaskBean.setAssigns(MapUtils.getString(taskMap, "assigns"));
                mpxjTaskBean.setAssignsDesc(MapUtils.getString(taskMap, "assignsdesc"));

                // 处理时间相关属性
                if (taskMap.get("startTime") != null) {
                    Date startTime = (Date) taskMap.get("startTime");
                    mpxjTaskBean.setStart(startTime.getTime());
                }
                if (taskMap.get("endTime") != null) {
                    Date endTime = (Date) taskMap.get("endTime");
                    mpxjTaskBean.setEnd(endTime.getTime());
                }

                mpxjTaskBean.setDuration(MapUtils.getInteger(taskMap, "duration"));
                mpxjTaskBean.setDurationTimeUnit(MapUtils.getString(taskMap, "durationTimeUnit"));

                mpxjTaskBean.setStartIsMilestone(ProjectPlanConstant.START_IS_MILESTONE);
                mpxjTaskBean.setEndIsMilestone(ProjectPlanConstant.END_IS_MILESTONE);
                String isMilestone = MapUtils.getString(taskMap, "isMilestone");
                if ("1".equals(isMilestone)) {
                    mpxjTaskBean.setEndIsMilestone(true);
                }

                Integer hasChild = MapUtils.getInteger(taskMap, "hasChild");
                mpxjTaskBean.setHasChild(hasChild == 1);

                mpxjTaskBean.setMlid(MapUtils.getInteger(taskMap, "mlid"));

                mpxjTaskBean.setCollapsed(ProjectPlanConstant.IS_COLLAPSED);
                mpxjTaskBean.setCanWrite(ProjectPlanConstant.CAN_WRITE);
                mpxjTaskBean.setCanAdd(ProjectPlanConstant.CAN_ADD);
                mpxjTaskBean.setCanDelete(ProjectPlanConstant.CAN_DELETE);
                mpxjTaskBean.setCanAddIssue(ProjectPlanConstant.CAN_ADD_ISSUE);
                mpxjTaskBean.setRelevance(0);

                mpxjTaskBeanList.add(mpxjTaskBean);
            }

            // 项目计划添加任务信息
            mpxjBean.setTasks(mpxjTaskBeanList);
            return mpxjBean;
        }

        return null;
    }

    /**
     * 处理项目进度计划信息
     *
     * @param mpxjTaskBeanList WBS任务信息
     * @param proId 项目id
     * @param tcId 任务变更id
     */
    private void dealTask(List<MpxjTaskBean> mpxjTaskBeanList, Integer proId, Integer tcId) throws Exception {
        // 查询项目台账信息
        List<Map<String, Object>> proList = handlerService.findBySql("select subjectno, personincharge, proleader, deptcode, deptname from gq_proaccount where id = "+ proId);
        Map<String, Object> proMap = proList.get(0);
        String subjectno = MapUtils.getString(proMap, "subjectno");
        Integer personincharge = MapUtils.getInteger(proMap, "personincharge");
        Integer proleader = MapUtils.getInteger(proMap, "proleader");
        String deptCode = MapUtils.getString(proMap, "deptcode");
        String deptName = MapUtils.getString(proMap, "deptname");

        int recordId = 1;
        for (MpxjTaskBean mpxjTaskBean : mpxjTaskBeanList) {
            String taskId = mpxjTaskBean.getId();
            String name = StringUtils.isEmpty(mpxjTaskBean.getName()) ? "" : mpxjTaskBean.getName();
            Integer level = mpxjTaskBean.getLevel() == null ? 0 : mpxjTaskBean.getLevel();
            String type = StringUtils.isEmpty(mpxjTaskBean.getTypeId()) ? "" : mpxjTaskBean.getTypeId();
            String typeDesc = StringUtils.isEmpty(mpxjTaskBean.getType()) ? "" : mpxjTaskBean.getType();
            String depends = StringUtils.isEmpty(mpxjTaskBean.getDepends()) ? "" : mpxjTaskBean.getDepends();
            Integer hasChild = mpxjTaskBean.isHasChild() ? 1 : 0;

            long start = mpxjTaskBean.getStart();
            long end = mpxjTaskBean.getEnd();
            String startTime = DateUtils.dateToStr(new Date(start), "yyyy-MM-dd HH:mm:ss");
            String endTime = DateUtils.dateToStr(new Date(end), "yyyy-MM-dd HH:mm:ss");
            String description = StringUtils.isEmpty(mpxjTaskBean.getDescription()) ? "" : mpxjTaskBean.getDescription();
            Integer duration = mpxjTaskBean.getDuration() == null ? 0 : mpxjTaskBean.getDuration();
            String durationTimeUnit = mpxjTaskBean.getDurationTimeUnit() == null ? "天" : mpxjTaskBean.getDurationTimeUnit();
            Integer manager = mpxjTaskBean.getManager() == null ? 0 : mpxjTaskBean.getManager();
            String managerName = StringUtils.isEmpty(mpxjTaskBean.getManagerName()) ? "" : mpxjTaskBean.getManagerName();
            Integer mlid = mpxjTaskBean.getMlid() == null ? 0 : mpxjTaskBean.getMlid();

            // 里程碑
            boolean isEndIsMilestone = mpxjTaskBean.isEndIsMilestone();
            String isMilestone = "0";
            if (isEndIsMilestone) {
                isMilestone = "1";
            }

            Map<String, Object> map = new HashMap<>(1);
            map.put("name", name);
            map.put("taskchglevel", level);
            map.put("taskparentchglevel", level-1);
            map.put("recordId", recordId);
            map.put("type", type);
            map.put("typeDesc", typeDesc);
            map.put("isMilestone", isMilestone);
            map.put("startTime", startTime);
            map.put("endTime", endTime);
            map.put("manager", manager);
            map.put("managername", managerName);
            map.put("description", description);
            map.put("duration", duration);
            map.put("durationTimeUnit", durationTimeUnit);
            map.put("hasChild", hasChild);
            map.put("mlid", mlid);

            map.put("proid", proId);
            map.put("tcid", tcId);
            map.put("subjectno", subjectno);
            map.put("personincharge", personincharge);
            map.put("proleader", proleader);
            map.put("deptcode", deptCode);
            map.put("deptname", deptName);
            map.put("depends", depends);

            if (taskId.startsWith("tmp_")) {
                map.put("parentId", -1);
                map.put("status", "未开始");
                map.put("taskstatus", "未开始");
                map.put("unfinishprocess", 100);
                handlerService.insert("gq_taskchgdtl", map);
            } else {
                map.put("id", taskId);
                handlerService.update("gq_taskchgdtl", map);
            }

            recordId++;
        }

        // 重新整理父子关系
        this.updParentId(proId, tcId);

        // 更新前置任务信息
        this.updPredecessors(proId, tcId);
    }
}
